/** *************************************************************************
 *  @file       multicast_ctr_init.c
 *  @brief	    网络初始化函数
 *  @date		2021/04/23
 *  @author		junshuai.li
 *  @version	0.0.1
 ****************************************************************************/
#include "multicast_ctr_init.h"

// 用于判断是否为第一次version.txt
u8 flag_file_open_num = 0;

void fwrite_file(u8 *const locla_mac, u64 hw_version, u8 *const name)
{
  FILE *fp = NULL;

  u8 buf[100] = {0};
  if (flag_file_open_num == 0)
  {
    fp = fopen("./version.txt", "w");
    flag_file_open_num++;
  }
  else
    fp = fopen("./version.txt", "a+");
  sprintf(buf, "%s\n", "*************************");
  fwrite(buf, sizeof(char), strlen(buf), fp);

  fwrite(name, sizeof(char), strlen(name), fp);
  sprintf(buf, "%s\n", ": ");
  fwrite(buf, sizeof(char), strlen(buf), fp);

  sprintf(buf, "locla_mac = %02x:%02x:%02x:%02x:%02x:%02x\n", locla_mac[0],
          locla_mac[1], locla_mac[2], locla_mac[3], locla_mac[4], locla_mac[5]);
  fwrite(buf, sizeof(char), strlen(buf), fp);

  sprintf(buf, "version = 0x%llx\n", hw_version);
  fwrite(buf, sizeof(char), strlen(buf), fp);
  fclose(fp);

  return;
}

void riprt_n(char *str)
{
  int len, i;

  if (str == NULL)
    return;
  len = strlen(str);
  if (len == 0)
    return;

  for (i = 0; i < len; i++)
  {
    if (str[i] == '\r' || str[i] == '\n')
      str[i] = '\t';
  }
}

int parse_multicast_info(char *buf, u16 *mid)
{
  int ret = 0;
  u16 tvalue16 = 0;

  cJSON *root_json = NULL;
  cJSON *multicsat_cfg_json = NULL;
  cJSON *multicast_json = NULL;
  cJSON *tmp_json = NULL;

  riprt_n(buf);
  root_json = cJSON_Parse(buf);

  if (!root_json)
  {
    printf("parse root_json error, Error before: [%s]\n", cJSON_GetErrorPtr());
    return -1;
  }

  multicsat_cfg_json = cJSON_GetObjectItem(root_json, "multicast_cfg_para");
  if (!multicsat_cfg_json)
  {
    printf("parse multicast_cfg_para error, Error before: [%s]\n",
           cJSON_GetErrorPtr());
    cJSON_Delete(root_json);
    return -1;
  }

  multicast_json = cJSON_GetObjectItem(multicsat_cfg_json, "multicast");
  if (!multicast_json)
  {
    printf("parse multicast_json error, Error before: [%s]\n",
           cJSON_GetErrorPtr());
    cJSON_Delete(root_json);
    return -1;
  }
  else
  {
    tmp_json = cJSON_GetObjectItem(multicast_json, "multicast_mid");
    if (!tmp_json)
    {
      printf("parse multicast_mid error, Error before: [%s]\n",
             cJSON_GetErrorPtr());
      cJSON_Delete(root_json);
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hx", &tvalue16);
      *mid = tvalue16;
      printf("multicast_mid = 0x%hx \n", *mid);
    }
  }

  cJSON_Delete(root_json);

  return ret;
}

int get_multicast_mid_from_file(u8 *cfg_file_name, u16 *mid)
{
  int ret = 0;

  FILE *fp;
  char *buf;
  fp = fopen(cfg_file_name, "r");

  if (fp == NULL)
  {
    printf("fopen %s error\n", cfg_file_name);
    return -1;
  }

  // 确定文件大小, 并将读取指针移回文件开始
  fseek(fp, 0, SEEK_END);
  long pos = ftell(fp);
  fseek(fp, 0, SEEK_SET);
  if (pos <= 0)
  {
    printf("%s Invalid!\n", cfg_file_name);
    fclose(fp);
    return -1;
  }

  // 根据文件大小申请内存空间, 注意这边要多申请1个字节用于存放'\0'
  buf = (char *)malloc(pos + 1);
  if (buf == NULL)
  {
    printf("No enough memory.");
  }
  bzero(buf, pos + 1);

  // 读取文件内容至buff
  int nread = fread(buf, pos, 1, fp);
  if (!nread)
  {
    printf("Failed to read the config file.");
    return -1;
  }

  // 解析json，获取multicast的mid信息
  ret = parse_multicast_info(buf, mid);

  if (buf != NULL)
  {
    free(buf);
  }

  // 关闭文件
  fclose(fp);

  return ret;
}

int multicast_ctr_init(u8 *network_inetrface, u16 *multicast_mid, u32 version)
{
  int ret = 0;
  u8 local_mac[6] = {0};
  u8 *cfg_file_name = NULL;

  // 初始化libnet和libpcap
  // char test_rule[64] = {0};
  // sprintf(test_rule,"%s","ether[0:2]=0x6626 && ether[2]=0x62 && ether[5]=0x4
  // && ether[12:2]=0xff01");

  /*配置过滤器*/
  struct sock_fprog filter;

#if 1
  struct sock_filter code[] = {
      {0x28, 0, 0, 0x00000000},
      {0x15, 0, 7, 0x00006626},
      {0x30, 0, 0, 0x00000002},
      {0x15, 0, 5, 0x00000062},
      {0x30, 0, 0, 0x00000005},
      {0x15, 0, 3, 0x00000004},
      {0x28, 0, 0, 0x0000000c},
      {0x15, 0, 1, 0x0000ff01},
      {0x06, 0, 0, 0x0000ffff},
      {0x06, 0, 0, 0x00000000},
  };

  filter.len = 10;
  filter.filter = code;
#endif
  // data_pkt_receive_init(test_rule,network_inetrface);//数据接收初始化
  ret =
      tsmp_pkt_send_recv_init(network_inetrface, filter); // 数据发送接收初始化
  if (ret == -1)
  {
    printf("tsmp_pkt_send_recv_init fail\n");
    return -1;
  }

  cfg_file_name = MULTICAST_JSON_FILE; // 初始配置文本
  ret = get_multicast_mid_from_file(cfg_file_name, multicast_mid);
  if (ret == -1)
  {
    printf("get_multicast_mid_from_file fail \n");
    return -1;
  }
  printf("get multicast_mid %d\n", *multicast_mid);
  set_controller_mac(*multicast_mid, MULTICAST_APP);

  // 获取multicast的Mac地址,multicast_mid是解析multicast_cfg.json中获取的
  get_controller_mac_from_mid(local_mac, *multicast_mid, MULTICAST_APP);
  fwrite_file(local_mac, version, "multicast");

  printf("*************MULTICAST_CTR_INIT_FINISH********************\n");
  write_debug_msg(
      "*************MULTICAST_CTR_INIT_FINISH********************\n");

  return 0;
}

int resource_clear(u8 *network_inetrface)
{
  tsmp_pkt_send_recv_destroy();
  multicast_context_destory();
  return 0;
}
